import { Material } from "./Material";
import { has, any } from "../core/logic";
import { textureLoader } from "../assets/loader/TextureLoader";
import { Engine } from "../Engine";
/**
* 材质类。
* @class
* @memberof w.material
*/
class SkyboxMaterial extends Material {
  /**
   * 创建基础材质
   * @constructor
   * @param {*} opts
   */
  constructor(opts = { side: "back" }) {
    opts.side = "back"
    opts.depthCompare = "always"
    super(opts);
    this.defuseLight = true
    this.materialType = 'SkyboxMaterial';
    this.map = opts.map;
    this.removeParam('material');
    this.autoUpdate = true;
    this.update();
  }
  get materialType() {
    return this._materialType;
  }
  set materialType(v) {
    this._materialType = v;
    this.addConfigParam("materialType", v);
    this.update();
    return this;
  }
  set map(v) {
    if (!has(v)) {
      return;
    }
    this.setState(false, 'map');
    this.registerTexture(v, 'map', (t) => {
      this._map = t;
      this.setState(true, 'map');
      this.addMapParam("map")
      if (this.has("map")) {
        this.textureToGPU(this.map.toGPU(), 'map');
      }
      this.update();
    })
    return this;
  }
  get map() {
    return this._map;
  }
  updateState() {
    let state = (this.getState("map") || this.getState("map") == undefined)
    this.setState(state);
  }

  update() {
    if (!this.autoUpdate) {
      return;
    }
    if (!this.getState()) {
      this.updateState();
    }
    if (!this.getState()) {
      return;
    }
    let oldhash = this.hash;
    this.updateHash();
    let state = (oldhash != this.hash);
    let old = this.getState("layout");
    if (!old) {
      this.setState(old ? old : state, "layout");
    }
    this.notice();
  }
  toGPU() {
    if (this.has("enableDarker")) {
      this.bufferToGPU(new Float32Array([this.enableDarker]), 'enableDarker', GPUShaderStage.FRAGMENT);
    }
    // 生成bindGroup和groupLayout
    if (this.getState("layout")) {
      const params = this.getAllParams()
      let entriesGroup2 = [], entriesLayout2 = []
      let entriesGroup3 = [], entriesLayout3 = []
      this.defs = {}
      this.config = {}
      for (let index = 0; index < params.length; index++) {
        const param = params[index];
        this.defs[param.name] = param.value;
        if (param.group === 2) {
          entriesGroup2.push(param.gpu.entry)
          entriesLayout2.push(param.gpu.layout)
        } else if (param.group === 3) {
          entriesGroup3.push(param.gpu.entry)
          entriesLayout3.push(param.gpu.layout)
        } else {
          this.config[param.name] = param.value
        }
      }
      // 生成layout与bindgroup
      if (entriesGroup2.length > 0) {
        this.grouplayouts2 = Engine.instance.device.createBindGroupLayout({
          label: "layout" + 2,
          entries: entriesLayout2
        });
        this.bindGroup2 = Engine.instance.device.createBindGroup({
          label: "bindGroup" + 2,
          layout: this.grouplayouts2,
          entries: entriesGroup2
        });
      }
      if (entriesGroup3.length > 0) {
        this.grouplayouts3 = Engine.instance.device.createBindGroupLayout({
          label: "layout" + 3,
          entries: entriesLayout3
        });
        this.bindGroup3 = Engine.instance.device.createBindGroup({
          label: "bindGroup" + 3,
          layout: this.grouplayouts3,
          entries: entriesGroup3
        });
      }

    }
  }
}
export { SkyboxMaterial }
